/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package es.uca.plii.helpers;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Clase estática para imprimir la salida. Se trata de un Singleton que sea accesible desde el parser.
 * @author Rafael Sánchez, Alfonso Sendra
 */
public class OutputChannel {

    /**
     * Instancia del Singleton
     */
    private static OutputChannel instance = null;

    /**
     * Initializador del Singleton. Crea un stream de salida, si se especificó archivo de salida.
     * @param salida
     * @return si es correcta la inicialización
     */
    public static boolean inicializa(String salida) {
        try {
            instance = new OutputChannel(salida);
        } catch (IOException ex) {
            System.out.println("Hay problemas para escribir al archivo " + salida + ": " + ex.getMessage());
            return false;
        }
        return true;
    }

    /**
     * Función estática para escribir en el dispositivo de salida.
     * Escribe en el archivo, si se especificó. Si no, escribe en la salida
     * estándard.
     * @param salida
     */
    public static void escribe(String salida) {
        if (instance != null) {
            instance.escribir(salida);
        }
    }

    /**
     * Termina y cierra la salida. Necesario para cerrar el stream, en caso de que se especifique
     */
    public static void terminar() {
        if (instance != null) {
            instance.cerrar();
        }

    }
    /**
     * Stream de salida para el archivo
     */
    private BufferedWriter out = null;

    /**
     * Flag que dice si se especificó archivo
     */
    private boolean hasFile = false;

    /**
     * Constructor privado de la instancia del Singleton
     * @param salida
     * @throws IOException
     */
    private OutputChannel(String salida) throws IOException {
        if (salida != null) {
            out = new BufferedWriter(new FileWriter(salida));
            hasFile = true;
        }

    }

    /**
     * Implementación privada de la función de salida
     * @param salida
     */
    private void escribir(String salida) {
        if (!hasFile) {
            System.out.print(salida);
        } else {
            try {
                out.write(salida);
                out.flush();
            } catch (IOException ex) {
                System.out.println("Hay problemas para escribir al archivo de salida: " + ex.getMessage());
            }
        }

    }

    /**
     * Cierra el stream de salida, si se especificó
     */
    private void cerrar() {
        try {
            if (out != null) {
                out.close();
            }
        } catch (IOException ex) {
            Logger.getLogger(OutputChannel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
